<?php
declare (strict_types = 1);

namespace app\wechat\controller;

use EasyWeChat\Factory;
use think\facade\Log;
use wpfly\Crypto;

class OfficialAccount extends BaseController
{
    public function index()
    {
        //微信公众号开发模式服务端
        $config = [
            'app_id' => settings('wechat_appid'),
            'secret' => settings('wechat_appsecret'),
            'token' => settings('wechatapi_token'),
        ];
        $app = Factory::officialAccount($config);

        $app->server->push(function ($message) use ($app) {
            Log::record(json_encode($message, JSON_UNESCAPED_UNICODE));
            switch ($message['MsgType']) {
                case 'event':
                    switch ($message['Event']) {
                        case 'subscribe':
                            return "您好！欢迎关注我!";
                            break;
                        case 'CLICK':
                            return "您需要的功能正在马不停蹄地开发着!";
                            break;
                    }
                    break;
                case 'text':
                    return "您的消息已收到，感谢您的反馈!";
                    break;
            }
        });

        $response = $app->server->serve();
        return response($response->getContent(), 200, ['Content-Type' => 'application/xml; charset=utf-8']);
    }

    public function authRedirect()
    {
        $data = $this->request->get();
        if (empty($data)) {
            failure(10);
        }
        if (!verify_sign($data, config('app.officialaccount_auth_secret'))) {
            failure(11);
        }
        if (!verify_timestamp($data, 300)) {
            failure(12);
        }
        sign_clear($data);
        if (empty($data['logic_url'])) {
            failure(105);
        }
        $appid = settings('wechat_appid');
        $appsecret = settings('wechat_appsecret');
        if (!empty($data['appid']) && !empty($data['appsecret'])) {
            $crypto = new Crypto();
            $appsecret = $crypto->aesDecrypt($data['appsecret']);
            $appid = $data['appid'];
        }
        $data['appid'] = $appid;
        $data['appsecret'] = $appsecret;
        $state = sign_data($data, '', false);
        $cacheId = "cache_wechat_auth_{$state}";
        cache($cacheId, $data, 300);
        $config = [
            'app_id' => $data['appid'],
            'secret' => $data['appsecret'],
            'oauth' => [
                'scopes' => ['snsapi_userinfo'],
                'callback' => '/wechat/OfficialAccount/authCallback',
            ],
        ];
        $app = Factory::officialAccount($config);
        $url = $app->oauth->with(['state' => $state])->redirect()->getTargetUrl();
        return redirect($url);
    }

    public function authCallback()
    {
        $state = $this->request->get('state');
        if (empty($state) || !preg_match('/^[0-9a-fA-F]{40}$/', $state)) {
            failure(106);
        }
        $cacheId = "cache_wechat_auth_{$state}";
        $data = cache($cacheId);
        if (empty($data)) {
            failure(107);
        }
        cache($cacheId, null);
        $config = [
            'app_id' => $data['appid'],
            'secret' => $data['appsecret'],
        ];
        $app = Factory::officialAccount($config);
        $user = $app->oauth->user()->getOriginal();
        $user['appid'] = $data['appid'];
        //保存微信粉丝信息
        $this->db->transaction(function () use (&$fansId, $user) {
            $fansId = app('app\service\WechatFansService')->saveInfo($user);
        });
        //附加粉丝信息
        $data['wechatfans_id'] = $fansId;
        $data['nickname'] = $user['nickname'];
        $data['headimgurl'] = $user['headimgurl'];
        $data['openid'] = $user['openid'];
        $logic_url = $data['logic_url'];
        unset($data['logic_url']);
        unset($data['appsecret']);
        $data = sign_data($data, config('app.officialaccount_auth_secret'));
        $logic_url .= (strpos($logic_url, '?') !== false) ? '&' : '?';
        $logic_url .= http_build_query($data);
        return redirect($logic_url);
    }

    public function login()
    {
        $data = $this->request->get();
        if (empty($data)) {
            failure(10);
        }
        if (!verify_sign($data, config('app.officialaccount_auth_secret'))) {
            failure(11);
        }
        if (!verify_timestamp($data, 300)) {
            failure(12);
        }
        sign_clear($data);
        if (empty($data['from_url']) || empty($data['wechatfans_id']) || !isset($data['nickname']) || !isset($data['headimgurl']) || empty($data['openid'])) {
            failure(109);
        }
        $from_url = $data['from_url'];
        unset($data['from_url']);
        $token = sign_data($data, '', false);
        session("wechat_login_{$token}", $data);
        cookie('wechat_auth', $token, config('session.expire'));
        return redirect($from_url);
    }
}
